package com.ngc.mall.common.configure.exception;

import com.ngc.mall.common.configure.response.ResponseCode;
import com.ngc.mall.common.configure.response.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import reactor.core.publisher.Mono;

import java.nio.file.AccessDeniedException;
import java.util.stream.Collectors;
@Slf4j
@RestControllerAdvice
public class BusinessExceptionHandler {

        @ExceptionHandler({BusinessException.class, Exception.class})
        public ResponseEntity<?> handlerException(Exception ex) {
            ResponseResult responseResult = null;

            // 业务异常
            if (ex instanceof BusinessException) {
                BusinessException businessException = (BusinessException)ex;
                responseResult = new ResponseResult();
                responseResult.setCode(businessException.getCode());
                responseResult.setMessage(businessException.getMessage());
                log.warn("[全局业务异常]\r\n业务编码：{}\r\n异常记录：{}", businessException.getCode(), businessException.getMessage());
            }

            // 统一处理 JSON 参数验证
            else if (ex instanceof MethodArgumentNotValidException) {
                MethodArgumentNotValidException methodArgumentNotValidException = (MethodArgumentNotValidException) ex;
                BindingResult bindingResult = methodArgumentNotValidException.getBindingResult();
                String msg = bindingResult.getFieldErrors()
                        .stream()
                        .map(FieldError::getDefaultMessage)
                        .distinct()
                        .collect(Collectors.joining(","));

                responseResult = new ResponseResult();
                responseResult.setCode(HttpStatus.BAD_REQUEST.value());
                responseResult.setMessage(msg);
            }

            // 统一处理表单绑定验证
            else if (ex instanceof BindException) {
                BindException bindException = (BindException) ex;
                BindingResult bindingResult = bindException.getBindingResult();
                String msg = bindingResult.getAllErrors()
                        .stream()
                        .map(DefaultMessageSourceResolvable::getDefaultMessage)
                        .distinct()
                        .collect(Collectors.joining(","));

                responseResult = new ResponseResult();
                responseResult.setCode(HttpStatus.BAD_REQUEST.value());
                responseResult.setMessage(msg);
            }

            // 无访问权限
            else if (ex instanceof AccessDeniedException) {
                responseResult = new ResponseResult(ResponseCode.PERMISSION_NO_ACCESS);
            }

            // 未知错误
            else {
                responseResult = new ResponseResult(ResponseCode.UNKNOWN);
                log.error(ex.getMessage());
                ex.printStackTrace();
            }

            return new ResponseEntity<>(responseResult, HttpStatus.OK);
        }


}
